package org.example.commodity.activity.service;

import cn.hutool.core.util.ObjectUtil;
import org.example.commodity.activity.entity.ActivityInfo;
import org.example.commodity.activity.entity.CommodityActivitySpecSku;
import org.example.commodity.activity.entity.CommodityActivityVirtualCard;
import org.example.commodity.activity.entity.CommoditySkuActivityAttrDto;
import org.example.commodity.activity.exception.CommodityActivityException;
import org.example.commodity.activity.queue.CommodityActivityMessagePushService;
import org.example.commodity.activity.queue.CommodityActivityPurchaseParam;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class CommodityActivityService {

    private final Map<String, BaseCommodityActivityProcessor<? extends ActivityInfo>> processorMap;
    private final CommodityActivityMessagePushService pushServiceMessage;

    /**
     * 默认超时时间
     */
    private static final Integer DEFAULT_TIME_OUT = 10 * 24 * 60 * 60;

    public CommodityActivityService(List<BaseCommodityActivityProcessor<? extends ActivityInfo>> processors,
                                    CommodityActivityMessagePushService pushServiceMessage) {

        this.processorMap = processors.stream().collect(Collectors.toMap(BaseCommodityActivityProcessor::getActivityType, item -> item));
        this.pushServiceMessage = pushServiceMessage;
    }

    public List<CommodityActivitySpecSku> listCommoditySku(Long commodityId, String activityType) {
        BaseCommodityActivityProcessor<? extends ActivityInfo> activityProcessor = processorMap.get(activityType);
        if (ObjectUtil.isNull(activityProcessor)) {
            throw new CommodityActivityException("未注册的活动类型！");
        }
        List<CommodityActivitySpecSku> skuList = activityProcessor.listActivityCommoditySku(commodityId);
        skuList.forEach(item -> {
            CommoditySkuActivityAttrDto activityAttr = activityProcessor.getActivityAttr(item.getId());
            assert activityAttr != null;
            item.setActivityAttr(activityAttr)
                    .setPrice(activityAttr.getActivityPrice())
                    .setStocks(activityAttr.getRemainingStocks());
        });

        return skuList;
    }

    public List<CommodityActivityVirtualCard> listCommodityVirtualCard(Long commodityId, String activityType) {
        BaseCommodityActivityProcessor<? extends ActivityInfo> activityProcessor = processorMap.get(activityType);
        if (ObjectUtil.isNull(activityProcessor)) {
            throw new CommodityActivityException("未注册的活动类型！");
        }
        List<CommodityActivityVirtualCard> virtualCardList = activityProcessor.listActivityCommodityVirtualCard(commodityId);
        virtualCardList.forEach(item -> {
            CommoditySkuActivityAttrDto activityAttr = activityProcessor.getActivityAttr(item.getId());
            assert activityAttr != null;
            item.setActivityAttr(activityAttr)
                    .setPrice(activityAttr.getActivityPrice())
                    .setStocks(activityAttr.getRemainingStocks());
        });
        return virtualCardList;
    }

    public CommoditySkuActivityAttrDto getActivityAttr(Long commoditySkuId, String activityType) {
        BaseCommodityActivityProcessor<? extends ActivityInfo> activityProcessor = processorMap.get(activityType);
        if (ObjectUtil.isNull(activityProcessor)) {
            throw new CommodityActivityException("未注册的活动类型！");
        }
        return activityProcessor.getActivityAttr(commoditySkuId);
    }

    /**
     * 根据活动类型获取最小的超时时间
     * @param activityTypes 活动类型集合
     * @return Integer
     */
    public Integer getMinActivityTimeOut(List<String> activityTypes) {
        return activityTypes.stream().map(activityType -> {
            BaseCommodityActivityProcessor<? extends ActivityInfo> activityProcessor = processorMap.get(activityType);
            return activityProcessor.getActivityTimeOut();
        }).min(Integer::compareTo).orElse(DEFAULT_TIME_OUT);
    }

    /**
     * 减少活动缓存库存
     * 然后使用消息队列异步处理同步数据库数据
     */
    public void decreaseActivityRedisStocks(Long activityId, Long commoditySkuId, String activityType, Integer quantity, Long customerId) {
        BaseCommodityActivityProcessor<? extends ActivityInfo> activityProcessor = processorMap.get(activityType);
        if (ObjectUtil.isNull(activityProcessor)) {
            throw new CommodityActivityException("未注册的活动类型！");
        }
        activityProcessor.decreaseActivityRedisStocks(activityId,commoditySkuId,quantity);
        activityProcessor.addCustomerPurchaseNumber(commoditySkuId,customerId,quantity);
        pushServiceMessage.publish(new CommodityActivityPurchaseParam(activityType,activityId,quantity));
    }
    /**
     * 恢复活动缓存库存
     * 然后使用消息队列异步处理同步数据库数据
     */
    public void increaseActivityRedisStocks(Long activityId, Long commoditySkuId, String activityType, Integer quantity, Long customerId) {
        BaseCommodityActivityProcessor<? extends ActivityInfo> activityProcessor = processorMap.get(activityType);
        if (ObjectUtil.isNull(activityProcessor)) {
            throw new CommodityActivityException("未注册的活动类型！");
        }
        activityProcessor.increaseActivityRedisStocks(activityId,commoditySkuId,quantity);
        activityProcessor.addCustomerPurchaseNumber(commoditySkuId,customerId,-1 * quantity);
        pushServiceMessage.publish(new CommodityActivityPurchaseParam(activityType, activityId,-1 *quantity));
    }
    /**
     * 减少活动数据库库存
     */
    public void decreaseActivityStocks( String activityType, CommodityActivityPurchaseParam purchaseParam) {
        BaseCommodityActivityProcessor<? extends ActivityInfo> activityProcessor = processorMap.get(activityType);
        if (ObjectUtil.isNull(activityProcessor)) {
            throw new CommodityActivityException("未注册的活动类型！");
        }
        activityProcessor.decreaseActivityStocks(purchaseParam.getActivityId(), purchaseParam.getQuantity());
    }
    /**
     * 获取用户购买数量
     */
    public Long getCustomerPurchaseNumber( String activityType, Long commoditySkuId, Long customerId) {
        BaseCommodityActivityProcessor<? extends ActivityInfo> activityProcessor = processorMap.get(activityType);
        if (ObjectUtil.isNull(activityProcessor)) {
            throw new CommodityActivityException("未注册的活动类型！");
        }
        return activityProcessor.getCustomerPurchaseNumber(commoditySkuId,customerId);
    }
}
